
package com.jf.cloud.product.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.jf.cloud.api.combo.feign.ComboFeignClient;
import com.jf.cloud.api.combo.feign.ComboSpuFeignClient;
import com.jf.cloud.api.delivery.feign.DeliveryFeignClient;
import com.jf.cloud.api.product.feign.SpuFeignClient;
import com.jf.cloud.api.product.util.ProductLangUtil;
import com.jf.cloud.common.cache.constant.CacheNames;
import com.jf.cloud.common.cache.util.CacheManagerUtil;
import com.jf.cloud.common.cache.util.RedisUtil;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.i18n.I18nMessage;
import com.jf.cloud.common.order.util.OrderLangUtil;
import com.jf.cloud.common.order.vo.ShopCartItemVO;
import com.jf.cloud.common.product.constant.SpuType;
import com.jf.cloud.common.product.constant.SupplierDeliveryType;
import com.jf.cloud.common.product.vo.*;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.security.AuthUserContext;
import com.jf.cloud.product.dto.shopcart.ChangeShopCartItemDTO;
import com.jf.cloud.product.dto.shopcart.CheckShopCartItemDTO;
import com.jf.cloud.product.mapper.ShopCartItemMapper;
import com.jf.cloud.product.model.ShopCartItem;
import com.jf.cloud.product.service.ShopCartService;
import com.jf.cloud.product.service.SkuService;
import com.jf.cloud.product.service.SkuStockService;
import com.jf.cloud.product.service.SpuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 购物车
 *
 * @author zz
 * @date 2020-11-20 15:47:32
 */
@Service
public class ShopCartServiceImpl implements ShopCartService {

    @Autowired
    private ShopCartItemMapper shopCartItemMapper;
    @Autowired
    private SpuFeignClient spuFeignClient;
    @Autowired
    private CacheManagerUtil cacheManagerUtil;
    @Autowired
    private SpuService spuService;
    @Autowired
    private DeliveryFeignClient deliveryFeignClient;



    @Override
    @CacheEvict(cacheNames = CacheNames.SHOP_CART_ITEM_COUNT, key = "#userId")
    public void deleteShopCartItemsByShopCartItemIds(Long userId,List<Long> shopCartItemIds) {
        if (CollectionUtil.isEmpty(shopCartItemIds)) {
            return;
        }
        shopCartItemMapper.deleteShopCartItemsByShopCartItemIds(userId, shopCartItemIds);
    }

    @Override
    @CacheEvict(cacheNames = CacheNames.SHOP_CART_ITEM_COUNT, key = "#userId")
    public void addShopCartItem(Long userId, ChangeShopCartItemDTO param, Long priceFee, Long categoryId) {
        ShopCartItem shopCartItem = new ShopCartItem();
        shopCartItem.setCount(param.getCount());
        shopCartItem.setSpuId(param.getSpuId());
        shopCartItem.setShopId(param.getShopId());
        shopCartItem.setUserId(userId);
        shopCartItem.setSkuId(param.getSkuId());
        shopCartItem.setCategoryId(categoryId);
        shopCartItem.setDistributionUserId(param.getDistributionUserId());
        shopCartItem.setDiscountId(0L);
        shopCartItem.setIsChecked(1);
        shopCartItem.setPriceFee(priceFee);
        shopCartItem.setComboId(param.getComboId());
        shopCartItem.setComboCount(param.getComboCount());
        shopCartItem.setParentCartItemId(param.getParentCartItemId());
        shopCartItemMapper.save(shopCartItem);
    }

    @Override
    @CacheEvict(cacheNames = CacheNames.SHOP_CART_ITEM_COUNT, key = "#userId")
    public void updateShopCartItem(Long userId,ShopCartItem shopCartItem) {
        shopCartItemMapper.update(shopCartItem);
    }

    @Override
    @CacheEvict(cacheNames = CacheNames.SHOP_CART_ITEM_COUNT, key = "#userId")
    public void deleteAllShopCartItems(Long userId) {
        shopCartItemMapper.deleteAllShopCartItems(userId);
    }

    @Override
    public List<ShopCartItemVO> getShopCartItems() {
        Long userId = AuthUserContext.get().getUserId();
        List<ShopCartItemVO> shopCartItems = shopCartItemMapper.getShopCartItems(userId, false, null, I18nMessage.getLang());
        for (ShopCartItemVO shopCartItem : shopCartItems) {
            shopCartItem.setTotalAmount(shopCartItem.getCount() * shopCartItem.getSkuPriceFee());
            shopCartItem.setActualTotal(shopCartItem.getTotalAmount());
            shopCartItem.setShareReduce(0L);
            OrderLangUtil.shopCartItemLang(shopCartItem);
            shopCartItem.setSpuLangList(null);
            shopCartItem.setSkuLangList(null);
            // 判断下是否为供应商商品,如果是商家代销供应商商品且为供应商发货设置供应商信息
            if (!Objects.equals(shopCartItem.getSupplierId(),0L) && Objects.equals(shopCartItem.getSupplierDeliveryType(),1)) {
                ServerResponseEntity<SpuAndSkuVO> spuAndSkuResponse = spuFeignClient.getSpuAndSkuAndRateById(shopCartItem.getSpuId(),shopCartItem.getSkuId(),true);
                if (!spuAndSkuResponse.isSuccess()) {
                    throw new LuckException(spuAndSkuResponse.getMsg());
                }
                SkuVO sku = spuAndSkuResponse.getData().getSku();
                SpuVO spu = spuAndSkuResponse.getData().getSpu();
                shopCartItem.setSupplierId(spu.getSupplierId());
                shopCartItem.setDeliveryTemplateId(spu.getDeliveryTemplateId());
                shopCartItem.setSupplierPriceFee(sku.getSupplyPriceFee());
                shopCartItem.setSpuName(spu.getName());
//                shopCartItem.setTotalPurchaseAmount(shopCartItem.getCount() * sku.getSupplyPriceFee());
//                shopCartItem.setSupplierSpuId(spu.getSupplierSpuId());
//                shopCartItem.setSupplierSkuId(sku.getSupplierSkuId());
//                shopCartItem.setSupplierRate(spu.getRate());
//                shopCartItem.setSkuChoiceStatus(shopCartItem.getSkuChoiceStatus());
//                shopCartItem.setMeasureUnit(shopCartItem.getMeasureUnit());
            } else{
                shopCartItem.setSupplierId(0L);
            }
            //判断用户的默认地址是否在配送范围内
            SpuVO spuVo = spuFeignClient.getById(shopCartItem.getSpuId()).getData();
            if(Objects.equals(spuVo.getSpuType(), SpuType.ACTIVE.value()) || Objects.equals(shopCartItem.getSpuMold(), 1) || Objects.equals(userId, null)){
                shopCartItem.setIsDelivery(true);
            }else {
                shopCartItem.setIsDelivery(deliveryFeignClient.checkAddr(shopCartItem.getDeliveryTemplateId(), userId, 0L).getData());
            }
        }
        return shopCartItems;
    }

    @Override
    public List<ShopCartItemVO> getShopCartExpiryItems() {
        Long userId = AuthUserContext.get().getUserId();
        List<ShopCartItemVO> shopCartItems = shopCartItemMapper.getShopCartItems(userId, true, null, I18nMessage.getLang());
        List<ShopCartItemVO> itemVOS = shopCartItems.stream().filter(shopCartItemVO ->
            Objects.equals(shopCartItemVO.getSupplierDeliveryType(), SupplierDeliveryType.SUPPLIER_DELIVERY.value())
        ).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(itemVOS)){
            List<Long> supplierSpuIds =  itemVOS.stream().map(ShopCartItemVO::getSupplierSpuId).collect(Collectors.toList());
            List<SpuVO> supplierSpuVOList = spuService.listSpuBySpuIds(supplierSpuIds);
            Map<Long, SpuVO> supplierSpuMap = supplierSpuVOList.stream().collect(Collectors.toMap(SpuVO::getSpuId, spuVO -> spuVO));
            for(ShopCartItemVO shopCartItemVO : shopCartItems){
                if(Objects.equals(shopCartItemVO.getSupplierDeliveryType(), SupplierDeliveryType.SUPPLIER_DELIVERY)){
                    shopCartItemVO.setSpuName(supplierSpuMap.get(shopCartItemVO.getSupplierSpuId()).getName());
                }
            }
        }

        ProductLangUtil.shopCartItemList(shopCartItems);
        for (ShopCartItemVO shopCartItem : shopCartItems) {
            shopCartItem.setTotalAmount(shopCartItem.getCount() * shopCartItem.getSkuPriceFee());
            shopCartItem.setActualTotal(shopCartItem.getTotalAmount());
        }
        return shopCartItems;
    }

    @Override
    @Cacheable(cacheNames = CacheNames.SHOP_CART_ITEM_COUNT, key = "#userId")
    public Integer getShopCartItemCount(Long userId) {
        return shopCartItemMapper.getShopCartItemCount(userId);
    }

    @Override
    public List<ShopCartItemVO> getCheckedShopCartItems() {
        Long userId = AuthUserContext.get().getUserId();
        return shopCartItemMapper.getShopCartItems(userId, false, true, I18nMessage.getLang());
    }

    @Override
    public void removeShopCartItemCache(List<Long> spuIds) {
        List<String> userIds = shopCartItemMapper.listUserIdBySpuIds(spuIds);
        if (CollectionUtil.isEmpty(userIds)) {
            return;
        }
        for (String userId : userIds) {
            cacheManagerUtil.evictCache(CacheNames.SHOP_CART_ITEM_COUNT, userId);
        }
    }

    @Override
    public void removeShopCartItemCacheBySupplierSpuIds(List<Long> supplierSpuIds) {
        if (CollUtil.isEmpty(supplierSpuIds)) {
            return;
        }
        List<String> userIds = shopCartItemMapper.listUserIdBySupplierSpuIds(supplierSpuIds);
        if (CollectionUtil.isEmpty(userIds)) {
            return;
        }
        for (String userId : userIds) {
            cacheManagerUtil.evictCache(CacheNames.SHOP_CART_ITEM_COUNT, userId);
        }
    }

    @Override
    public void checkShopCartItems(Long userId, List<CheckShopCartItemDTO> params) {
        shopCartItemMapper.checkShopCartItems(userId, params);
    }

    @Override
    public void updateIsClosedByShopIds(List<Long> shopIds, Integer isClosed) {
        if (shopIds == null || shopIds.size() == 0) {
            return;
        }
        shopCartItemMapper.updateIsCloseByShopIds(shopIds, isClosed);
    }

    @Override
    public void updateShopCartItemBatch(Long userId, List<ShopCartItem> shopCartItem) {
        shopCartItemMapper.updateShopCartItemBatch(shopCartItem);
    }

    @Override
    public Long getCartItemBySpuIdAndComboId(Long spuId, Long comboId, Long userId,Long skuId) {
        ShopCartItemVO cartItemBySpuIdAndComboId = shopCartItemMapper.getCartItemBySpuIdAndComboId(spuId, comboId, userId, skuId);
        if (Objects.isNull(cartItemBySpuIdAndComboId)){
           return null;
        }else {
            return cartItemBySpuIdAndComboId.getCartItemId();
        }
    }

    @Override
    public void deleteCartByComboUpdate(List<Long> comboIdList, Long spuId, Long skuId) {
        // 清除购物车商品数量缓存
        removeShopCartItemCacheByComboId(comboIdList);
        shopCartItemMapper.deleteCartByComboUpdate(comboIdList,spuId,skuId);
    }

    public void removeShopCartItemCacheByComboId(List<Long> comboId) {
        List<String> userIds = shopCartItemMapper.listUserIdByComboIds(comboId);
        if (CollectionUtil.isEmpty(userIds)) {
            return;
        }
        for (String userId : userIds) {
            cacheManagerUtil.evictCache(CacheNames.SHOP_CART_ITEM_COUNT, userId);
        }
    }

    @Override
    public void deleteCartByComboIdAndSpuIdS(Long comboId, List<Long> spuIdList) {
        removeShopCartItemCache(spuIdList);
        shopCartItemMapper.deleteCartByComboIdAndSpuIdS(comboId,spuIdList);
    }

    @Override
    public void deleteCartByComboIdAndSkuIdS(Long comboId, List<Long> skuIdList) {
        removeShopCartItemCacheBySkuIds(skuIdList);
        shopCartItemMapper.deleteCartByComboIdAndSkuIdS(comboId,skuIdList);

    }

    public void removeShopCartItemCacheBySkuIds(List<Long> skuIds) {
        List<String> userIds = shopCartItemMapper.listUserIdBySkuIds(skuIds);
        if (CollectionUtil.isEmpty(userIds)) {
            return;
        }
        for (String userId : userIds) {
            cacheManagerUtil.evictCache(CacheNames.SHOP_CART_ITEM_COUNT, userId);
            cacheManagerUtil.evictCache(CacheNames.SHOP_CART_ITEM_COUNT,userId);
            RedisUtil.del(CacheNames.SHOP_CART_ITEM_COUNT+userId);
        }
    }


    @Override
    public void updateCartSpuPriceByComboIdAndSkuId(Long comboId, Long skuId,Long price) {
        shopCartItemMapper.updateCartSpuPriceByComboIdAndSkuId(comboId,skuId,price);
    }

    @Override
    public List<Long> skuIdListByComboMainSkuId(List<Long> skuId) {
        return shopCartItemMapper.skuIdListByComboMainSkuId(skuId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCartComboCount(Long comboId, Long spuId, Integer count) {
        List<ShopCartItemVO> shopCartItemVOList = shopCartItemMapper.listShopCartItemByComboIdAndSpuId(comboId, spuId);
        if (shopCartItemVOList.size() == 0){
            return;
        }
        List<ShopCartItem> shopCartItemList = new ArrayList<>();
        ShopCartItem shopCartItem;
        for (ShopCartItemVO shopCartItemVO : shopCartItemVOList) {
            shopCartItem = new ShopCartItem();
            shopCartItem.setCartItemId(shopCartItemVO.getCartItemId());
            shopCartItem.setCount(count * shopCartItemVO.getComboCount());
            shopCartItem.setUserId(shopCartItemVO.getUserId());
            shopCartItemList.add(shopCartItem);
            // 移除用户购物车数量缓存
            cacheManagerUtil.evictCache(CacheNames.SHOP_CART_ITEM_COUNT, String.valueOf(shopCartItemVO.getUserId()));
        }
        shopCartItemMapper.updateShopCartItemBatch(shopCartItemList);

    }

}
